/**
 * 
 */
package com.nari.heatshare.dao;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.jdbc.core.JdbcTemplate;

import com.nari.baseinfo.model.IHeatMeter;
import com.nari.coreframe.dao.hibernate3.GenericDaoImpl;
import com.nari.heatshare.model.IAssignMeterDataGather;
import com.nari.heatshare.model.IHeatMeterDataGather;
import com.nari.platform.date.CalendarUtils;
import com.nari.platform.model.PageCond;
import com.nari.platform.model.ResponseMsg;
import com.nari.platform.model.ResultWithPageCond;
import com.nari.platform.unitconversion.EnergyConsumptionUnitUtil;
import com.nari.platform.utils.StringUtils;
import com.nari.rescontroller.dao.IResourceAccessControlDao;

/**
 * 
 * @author Xiaopeng
 * @date 2013-8-19
 */
public class HeatMeterDataGatherDaoImpl extends GenericDaoImpl<IHeatMeterDataGather, String> 
		implements IHeatMeterDataGatherDao {
	private IResourceAccessControlDao iResourceAccessControlDao;
	private JdbcTemplate jdbcTemplate;
	/**
	 * 分页查询热量表数据列表
	 * @param meterNo
	 * @param recordTime
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-6-23
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IHeatMeterDataGather> queryMeterDataPage(String meterNo, 
			Date recordTime, PageCond pageCond) throws Exception {
		Criteria listCriteria = this.getCurrentSession().createCriteria(IHeatMeterDataGather.class);
		Criteria countCriteria = this.getCurrentSession().createCriteria(IHeatMeterDataGather.class);
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResHql();
		if(!"".equals(authorityRes)) {
			List<Object> projectUIDList = this.runQueryHSqlObject(authorityRes);
			String formatProjectUIDList = StringUtils.formatIDsByList(projectUIDList);
			formatProjectUIDList = StringUtils.formatIDListWithSyntax(formatProjectUIDList, ",", "'");
			//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
			listCriteria.add(Restrictions.sqlRestriction("{alias}.t_meter_no in(select lower(t_meter_no) from BASE_HEAT_METER_INFO where t_project_id in("+formatProjectUIDList+"))"));
			countCriteria.add(Restrictions.sqlRestriction("{alias}.t_meter_no in(select lower(t_meter_no) from BASE_HEAT_METER_INFO where t_project_id in("+formatProjectUIDList+"))"));
		}
		// 热量表表号
		if (meterNo != null && !"".equals(meterNo.trim())) {
			listCriteria.add(Restrictions.ilike("meterNo", meterNo.trim().toLowerCase(), MatchMode.ANYWHERE));
			countCriteria.add(Restrictions.ilike("meterNo", meterNo.trim().toLowerCase(), MatchMode.ANYWHERE));
		}
		//抄表时间
		if(recordTime != null) {
			Date startTime = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(recordTime));
			Date endTime = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(recordTime));
			listCriteria.add(Restrictions.between("recordTime", startTime, endTime));
			countCriteria.add(Restrictions.between("recordTime", startTime, endTime));
		}
		// 统计结果集个数
		int total = ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
		// 结果集排序
		listCriteria.addOrder(Order.desc("recordTime")).addOrder(Order.asc("meterNo"));
		// 结果集分页
		listCriteria.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
		// 构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IHeatMeterDataGather> meterDataPage = new ResultWithPageCond<IHeatMeterDataGather>();
		meterDataPage.setList(listCriteria.list());
		meterDataPage.setPageCond(pageCond);
		return meterDataPage;
	}
	
	/**
	 * 根据定制查询特征信息(所属小区、抄表时间)统计热量表列表数据个数
	 * @param communityUID
	 * @param recordTime
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-12-11
	 */
	public int countCustomizedHmDataList(String communityUID, Date recordTime) throws Exception {
		String countHsql = "select count(*) from IHeatMeterDataGather hmd, IHeatMeter hm " +
				"where hm.communityID='"+communityUID+"' " +
				"and hmd.recordTime between :startTime and :endTime " +
				"and hmd.meterNo=hm.meterNo";
		Date recordTimeStart = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(recordTime));
		Date recordTimeEnd = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(recordTime));
		Query query = this.getCurrentSession().createQuery(countHsql);
		query.setTimestamp("startTime", recordTimeStart).setTimestamp("endTime", recordTimeEnd);
		return ((Long)query.uniqueResult()).intValue();
	}
	
	/**
	 * 根据定制查询特征信息(所属小区、抄表时间)查询热量表数据列表
	 * @param communityUID
	 * @param recordTime
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-12-11
	 */
	@SuppressWarnings("unchecked")
	public List<IHeatMeterDataGather> queryCustomizedHmDataList(String communityUID, 
			Date recordTime) throws Exception {
		String countHsql = "select hmd from IHeatMeterDataGather hmd, IHeatMeter hm " +
				"where hm.communityID='"+communityUID+"' " +
				"and hmd.recordTime between :startTime and :endTime " +
				"and hmd.meterNo=hm.meterNo " +
				"order by hmd.meterNo asc";
		Date recordTimeStart = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(recordTime));
		Date recordTimeEnd = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(recordTime));
		Query query = this.getCurrentSession().createQuery(countHsql);
		query.setTimestamp("startTime", recordTimeStart).setTimestamp("endTime", recordTimeEnd);
		return query.list();
	}

	/**
	 * 通过所属分摊域ID及抄表日期统计热量表数据的数量
	 * @param shareAreaUID 所属分摊域
	 * @param recordDate 抄表时间
	 * @param calculateType 热表计算关系
	 * 说明：add:加 subs:减
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-8
	 */
	public int countMeterDatasByAreaUIDAndDate(String shareAreaUID,
			Date recordDate, String calculateType) throws Exception {
		// 查询指定分摊域的热量表数据
		String hsql = "select count(*) from IHeatMeterDataGather hmd "
				+ "where hmd.meterNo in(select hm.meterNo "
				+ "from IHeatMeter hm where hm.shareAreaID='" + shareAreaUID;
		// 查询指定计算关系的热量表数据
		if (calculateType != null && !"".equals(calculateType)) {
			hsql += " and hm.calculateType='" + calculateType + "'";
		}
		hsql += "')";
		// 抄表日期
		if (recordDate != null) {
			// 抄表时间起始时间
			Date recordTimeStart = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(recordDate));
			// 抄表时间结束时间
			Date recordTimeEnd = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(recordDate));
			hsql += " and hmd.recordTime between :startDate and :endDate";
			Query query = this.getCurrentSession().createQuery(hsql);
			query.setTimestamp("startDate", recordTimeStart).setTimestamp("endDate", recordTimeEnd);
			return ((Long) query.uniqueResult()).intValue();
		}
		return ((Long) this.runQueryHSqlObject(hsql).get(0)).intValue();
	}
	
	/**
	 * 通过热量表表号及抄表日期统计热量表数据的数量
	 * @param meterNo 热量表表号
	 * @param recordDate 抄表时间
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-8
	 */
	public int countMeterDatasByMeterNoAndDate(String meterNo, Date recordDate) throws Exception {
		// 查询指定分摊域的热量表数据
		String hsql = "select count(*) from IHeatMeterDataGather hmd "
				+ "where hmd.meterNo='" + meterNo + "'";
		// 抄表日期
		if (recordDate != null) {
			// 抄表时间起始时间
			Date recordTimeStart = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(recordDate));
			// 抄表时间结束时间
			Date recordTimeEnd = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(recordDate));
			hsql += " and hmd.recordTime between :startDate and :endDate";
			Query query = this.getCurrentSession().createQuery(hsql);
			query.setTimestamp("startDate", recordTimeStart).setTimestamp("endDate", recordTimeEnd);
			return ((Long) query.uniqueResult()).intValue();
		}
		return ((Long) this.runQueryHSqlObject(hsql).get(0)).intValue();
	}
	
	/**
	 * 根据热量表表号、抄表时间查询最新上传的热量表数据(避免读取重复上传的热量表数据)
	 * @param meterNo 热量表表号(必填)
	 * @param recordDate 抄表日期
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-4
	 */
	@SuppressWarnings("unchecked")
	public IHeatMeterDataGather queryLatestMeterData(String meterNo, 
			Date recordDate) throws Exception {
		IHeatMeterDataGather meterData = null;
		if(meterNo!=null && !"".equals(meterNo.trim())) {
			String hsql = "from IHeatMeterDataGather hmd "
					+ "where hmd.meterNo='" + meterNo.trim() + "'";
			// 抄表日期起始时间
			Date recordTimeStart = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(recordDate));
			// 抄表日期结束时间
			Date recordTimeEnd = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(recordDate));
			hsql += " and hmd.recordTime between :startTime and :endTime";
			hsql += " order by hmd.recordTime desc";
			Query query = this.getCurrentSession().createQuery(hsql);
			query.setTimestamp("startTime", recordTimeStart).setTimestamp("endTime", recordTimeEnd);
			List<IHeatMeterDataGather> meterDataList = query.list();
			if(meterDataList!=null && meterDataList.size()>0) {
				meterData = meterDataList.get(0);
			}
		}
		return meterData;
	}
	
	/**
	 * 通过热量表列表及抄表日期统计热量表的累计热量
	 * @param meterList 热量表列表
	 * @param recordDate 抄表日期
	 * 说明：统计抄表日期当天最新的热量表数据,避免读取重复上传的热量表数据
	 * @return 累计热量的热量单位为MWh
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-4
	 */
	public double calcSumHeatByMeterListAndDate(List<IHeatMeter> meterList, 
			Date recordDate) throws Exception {
		BigDecimal sumHeatAddUp = new BigDecimal("0");
		if(meterList!=null && meterList.size()>0) {
			for(IHeatMeter heatMeter: meterList) {
				IHeatMeterDataGather meterData = this.queryLatestMeterData(heatMeter.getMeterNo(), recordDate);
				BigDecimal sumHeat = new BigDecimal(this.formatSumHeatToMWh(meterData));
				sumHeatAddUp = sumHeatAddUp.add(sumHeat);
			}
		}
		return sumHeatAddUp.doubleValue();
	}
	
	/**
	 * 通过热量表列表及抄表日期统计热量表的累计流量
	 * @param meterList 热量表列表
	 * @param recordDate 抄表日期
	 * 说明：统计抄表日期当天最新的热量表数据,避免读取重复上传的热量表数据
	 * @return 
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-4
	 */
	public double calcSumFlowByMeterListAndDate(List<IHeatMeter> meterList, 
			Date recordDate) throws Exception {
		BigDecimal sumFlowAddUp = new BigDecimal("0");
		if(meterList!=null && meterList.size()>0) {
			for(IHeatMeter heatMeter: meterList) {
				IHeatMeterDataGather meterData = this.queryLatestMeterData(heatMeter.getMeterNo(), recordDate);
				BigDecimal sumFlow = new BigDecimal(meterData.getSumFlow());
				sumFlowAddUp = sumFlowAddUp.add(sumFlow);
			}
		}
		return sumFlowAddUp.doubleValue();
	}

	/**
	 * 格式化热量表数据的累计热量，并以热量单位MWh返回累计热量
	 * @param meterData 热量表数据
	 * 说明：累计热量单位 1:MWh 2:kWh 3:Gj
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-8
	 */
	public double formatSumHeatToMWh(IHeatMeterDataGather meterData) throws Exception {
		String energyUnit = null;
		if (meterData != null) {
			if(meterData.getSumHeatUnit() == 1) {
				energyUnit = EnergyConsumptionUnitUtil.energyUnit_MWh;
			}
			if(meterData.getSumHeatUnit() == 2) {
				energyUnit = EnergyConsumptionUnitUtil.energyUnit_kWh;
			}
			if(meterData.getSumHeatUnit() == 3) {
				energyUnit = EnergyConsumptionUnitUtil.energyUnit_GJ;
			}
			return EnergyConsumptionUnitUtil.energyConvert2MWh(meterData.getSumHeat(), energyUnit);
		}
		return 0;
	}
	
	/**
	 * 根据分摊域分页查询所属热量表数据
	 * @param shareAreaUID 分摊域唯一标识(必须)
	 * @param meterNo 热量表表号(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-1
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IHeatMeterDataGather> queryMeterDataPageByAreaUID(String shareAreaUID, 
			String meterNo, PageCond pageCond) throws Exception {
		//热量表数据查询初始化信息
		int total = 0;
		List<IHeatMeterDataGather> meterDataList = new ArrayList<IHeatMeterDataGather>();
		//根据所属分摊域查询热量表数据
		if(shareAreaUID!=null && !"".equals(shareAreaUID)) {
			String hsql = "from IHeatMeterDataGather hmd " +
					"where hmd.meterNo in(select hm.meterNo " +
										"from IHeatMeter hm " +
										"where hm.shareAreaID='"+shareAreaUID+"')";
			if(meterNo!=null && !"".equals(meterNo.trim())) {
				hsql += " and lower(hmd.meterNo) like '%"+meterNo.trim().toLowerCase()+"%'";
			}
			//结果集总数查询
			String countHql = "select count(*) " + hsql;
			total = ((Long)this.getCurrentSession().createQuery(countHql).uniqueResult()).intValue();
			hsql += " order by hmd.recordTime desc";
			//热量表数据分页查询
			Query query = this.getCurrentSession().createQuery(hsql);
			query.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
			meterDataList = query.list();
		}
		//构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IHeatMeterDataGather> meterDataPage = new ResultWithPageCond<IHeatMeterDataGather>();
		meterDataPage.setList(meterDataList);
		meterDataPage.setPageCond(pageCond);
		return meterDataPage;
	}
	
	/**
	 * 根据热量表ID查询某个时间段内的热消耗量
	 * @param meterUID 热量表ID
	 * @param startDate 起始日期
	 * @param endDate 结束日期
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-9
	 */
	@SuppressWarnings("unchecked")
	public double queryHeatConsumeByMeterUID(String meterUID, Date startDate, 
			Date endDate) throws Exception {
		String hsql = "from IHeatMeterDataGather hmd " +
				"where hmd.meterNo=(select hm.meterNo " +
								"from IHeatMeter hm " +
								"where hm.id='"+meterUID+"')";
		// 抄表日期起始时间
		Date recordTimeStart = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(startDate));
		// 抄表日期结束时间
		Date recordTimeEnd = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(endDate));
		hsql += " and hmd.recordTime between :startTime and :endTime";
		hsql += " order by hmd.recordTime desc";
		Query query = this.getCurrentSession().createQuery(hsql);
		query.setTimestamp("startTime", recordTimeStart).setTimestamp("endTime", recordTimeEnd);
		List<IHeatMeterDataGather> meterDataList = query.list();
		double heatConsume = 0;
		if(meterDataList!=null && meterDataList.size()>2) {
			double endReadNum = meterDataList.get(0).getSumHeat();
			double startReadNum = meterDataList.get(meterDataList.size()-1).getSumHeat();
			heatConsume = new BigDecimal(endReadNum)
					.subtract(new BigDecimal(startReadNum), new MathContext(3, RoundingMode.HALF_UP))
					.doubleValue();
		}
		return heatConsume;
	}
	
	/**
	 * 根据热量表表号、抄表日期查询历史数据
	 * @param meterNo 热量表表号
	 * @param recordTime 抄表日期
	 * @param dataLimit 取回历史数据的条数，若不限制，则取回所有历史数据
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-14
	 */
	@SuppressWarnings("unchecked")
	public List<IHeatMeterDataGather> queryHistoryMeterData(String meterNo, 
			Date recordTime, Integer dataLimit) throws Exception {
		String hsql = "from IHeatMeterDataGather hmd " +
				"where hmd.meterNo='"+meterNo.trim()+"' ";
		Date minRecordTime = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(recordTime));
		hsql += "and hmd.recordTime<:deadline " +
				"order by hmd.recordTime desc";
		Query query = this.getCurrentSession().createQuery(hsql);
		query.setTimestamp("deadline", minRecordTime);
		if(dataLimit != null) {
			query.setFirstResult(0).setMaxResults(dataLimit);
		}
		return query.list();
	}
	
	/**
	 * 新增热量表平滑数据(包括人工干预数据和系统自动平滑数据)
	 * @param meterNo 热量表表号
	 * @param recordTime 抄表时间
	 * @param sumHeat 累计热量
	 * @param sumHeatUnit 累计热量单位 1:MWh 2:kWh 3:Gj
	 * @return 返回平滑数据的ID
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-14
	 */
	public String saveTransitionMeterData(String meterNo, Date recordTime, 
			double sumHeat, Integer sumHeatUnit) throws Exception {
		//查询相同表号、相同抄表日期的热量表数据
		int meterDataNum = countMeterDatasByMeterNoAndDate(meterNo, recordTime);
		if(meterDataNum > 0) {
			return "";
		}
		IHeatMeterDataGather heatMeterData = new IHeatMeterDataGather();
		heatMeterData.setMeterNo(meterNo);
		heatMeterData.setSumHeat(sumHeat);
		heatMeterData.setSumHeatUnit(sumHeatUnit);
		heatMeterData.setRecordTime(recordTime);
		heatMeterData.setSysHours(recordTime);
		heatMeterData.setWrongInfo("平滑数据");
		heatMeterData.setDataType(0);
		return this.saveEntity(heatMeterData);
	}
	
	/**
	 * 新增或修改热量表数据
	 * 说明：若存在相同表号、相同抄表日期的热量表数据，则无法新增
	 * @param meterData
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-11-13
	 */
	public ResponseMsg saveOrUpdateMeterData(IHeatMeterDataGather meterData) throws Exception {
		if(meterData.getId()!=null && !"".equals(meterData.getId())) {
			this.updateEntity(meterData, meterData.getId());
		} else {
			//查询相同表号、相同抄表日期的热量表数据
			int meterDataNum = countMeterDatasByMeterNoAndDate(meterData.getMeterNo(), meterData.getRecordTime());
			if(meterDataNum > 0) {
				return ResponseMsg.getInstance(false, "重复的热量表数据，无法新增！");
			}
			//保存热量表数据
			this.saveEntity(meterData);
		}
		return ResponseMsg.getInstance(true, "");
	}

	/**
	 * 批次删除某次任务上传数据（热量表的集中器号无法标识）
	 * @param recordTime 抄表日期(任务批次标识二)
	 * @param dataType 上传的数据类型,若未说明,则删除所有类型的数据
	 * 0:平滑数据	1:txt上传解析数据	2:定点上传数据
	 * 3:掌机上传数据	空或其他:未知来源数据
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-12-6
	 */
	public void deleteMeterDataUploadBatch(Date recordTime, Integer dataType) throws Exception {
		Date startDate = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(recordTime));
		Date endDate = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(recordTime));
		String hsql = "delete from IHeatMeterDataGather hmd " +
				"where hmd.recordTime between :startDate and :endDate";
		if(dataType != null) {
			hsql += " and hmd.dataType="+dataType;
		}
		Query query = this.getCurrentSession().createQuery(hsql);
		query.setTimestamp("startDate", startDate).setTimestamp("endDate", endDate);
		query.executeUpdate();
	}
	
	/**
	 * 统计某一时段内热表数据的记录数
	 * @param meterNo
	 * @param startDate
	 * @param endDate
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-28
	 */
	public int countMeterDataByPeriod(String meterNo, Date startDate, 
			Date endDate) throws Exception {
		String hsql = "select count(*) from IHeatMeterDataGather hmd " +
				"where hmd.meterNo='"+meterNo.trim()+"' " +
				"and hmd.recordTime between :startDate and :endDate";
		startDate = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(startDate));
		endDate = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(endDate));
		Query query = this.getCurrentSession().createQuery(hsql);
		query.setTimestamp("startDate", startDate).setTimestamp("endDate", endDate);
		return ((Long)query.uniqueResult()).intValue();
	}
	
	/**
	 * 查询某一时段内热表的紧前数据
	 * @param meterNo
	 * @param startDate
	 * @param endDate
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-28
	 */
	@SuppressWarnings("unchecked")
	public IHeatMeterDataGather queryNearlyFrontMeterData(String meterNo, Date startDate, 
			Date endDate) throws Exception {
		String hsql = "from IHeatMeterDataGather hmd " +
				"where hmd.meterNo='"+meterNo.trim()+"' " +
				"and hmd.recordTime between :startDate and :endDate " +
				"order by hmd.recordTime asc";
		startDate = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(startDate));
		endDate = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(endDate));
		Query query = this.getCurrentSession().createQuery(hsql);
		query.setTimestamp("startDate", startDate).setTimestamp("endDate", endDate);
		List<IHeatMeterDataGather> meterDataList = query.list();
		//查找紧前数据
		IHeatMeterDataGather meterData = null;
		if(meterDataList!=null && meterDataList.size()>0) {
			meterData = meterDataList.get(0);
		}
		return meterData;
	}
	
	/**
	 * 查询某一时段内热表的紧后数据
	 * @param meterNo
	 * @param startDate
	 * @param endDate
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-28
	 */
	@SuppressWarnings("unchecked")
	public IHeatMeterDataGather queryNearlyBackMeterData(String meterNo, Date startDate, 
			Date endDate) throws Exception {
		String hsql = "from IHeatMeterDataGather hmd " +
				"where hmd.meterNo='"+meterNo.trim()+"' " +
				"and hmd.recordTime between :startDate and :endDate " +
				"order by hmd.recordTime desc";
		startDate = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(startDate));
		endDate = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(endDate));
		Query query = this.getCurrentSession().createQuery(hsql);
		query.setTimestamp("startDate", startDate).setTimestamp("endDate", endDate);
		List<IHeatMeterDataGather> meterDataList = query.list();
		//查找紧前数据
		IHeatMeterDataGather meterData = null;
		if(meterDataList!=null && meterDataList.size()>0) {
			meterData = meterDataList.get(0);
		}
		return meterData;
	}
	
	/**
	 * 统计某一时段内热表的计量值
	 * 说明：若此时段内热表数据少于两条记录，则返回0
	 * @param meterNo
	 * @param startDate
	 * @param endDate
	 * @return 返回计量热量的热量单位为MWh
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-28
	 */
	public double calcMeterMeasureDataMWhByPeriod(String meterNo, Date startDate, 
			Date endDate) throws Exception {
		double measureData = 0;
		int recordCounter = this.countMeterDataByPeriod(meterNo, startDate, endDate);
		//查询统计时段内紧前数据、紧后数据
		if(recordCounter >= 2) {
			IHeatMeterDataGather startRecord = this.queryNearlyFrontMeterData(meterNo, startDate, endDate);
			IHeatMeterDataGather endRecord = this.queryNearlyBackMeterData(meterNo, startDate, endDate);
			//转化热量单位为MWh
			double startSumHeat = this.formatSumHeatToMWh(startRecord);
			double endSumHeat = this.formatSumHeatToMWh(endRecord);
			//计算统计时段内的计量结果
			measureData = new BigDecimal(endSumHeat)
					.subtract(new BigDecimal(startSumHeat))
					.doubleValue();
		}
		return measureData;
	}
	
	/**
	 * 批量新增热量表数据(数据更新不执行结果统计)
	 * @param meterDataList
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2015-1-20
	 */
	public int saveMeterDataBatch(List<IHeatMeterDataGather> meterDataList) throws Exception {
		//统计成功新增的热量表数据的个数
		int savedCounter = 0;
		if(meterDataList!=null && meterDataList.size()>0) {
			for(IHeatMeterDataGather meterData: meterDataList) {
				if(meterData.getId()!=null && !"".equals(meterData.getId())) {
					this.updateEntity(meterData, meterData.getId());
				} else {
					ResponseMsg rmsg = this.saveOrUpdateMeterData(meterData);
					if(rmsg.isSuccess()) {
						savedCounter++;
					}
				}
			}
		}
		return savedCounter;
	}

	

	/**
	 * 查询某一时段内热表的数据
	 * @param meterNo
	 * @param startDate
	 * @param endDate
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-28
	 */
	@SuppressWarnings("unchecked")
	public List<IHeatMeterDataGather> queryMeterData(String meterNo, Date startDate, 
			Date endDate) throws Exception {
		List<IHeatMeterDataGather> datas = new ArrayList<IHeatMeterDataGather>();
		String hsql = "from IHeatMeterDataGather hmd " +
				"where hmd.meterNo='"+meterNo.trim()+"' " +
				"and hmd.recordTime between :startDate and :endDate " +
				"order by hmd.recordTime asc";
		startDate = CalendarUtils.getMinCalBasedSrcCal(CalendarUtils.getInstance(startDate));
		endDate = CalendarUtils.getMaxCalBasedSrcCal(CalendarUtils.getInstance(endDate));
		Query query = this.getCurrentSession().createQuery(hsql);
		query.setTimestamp("startDate", startDate).setTimestamp("endDate", endDate);
		 datas = query.list();
		//查找紧前数据
		return datas;
	}
	
	
	/**
	 * 查询某一段时间内是否有热量表数据上传的数据  limit 是为了提高查询效率 方便优化器进行优化
	 * */
	@Override
	public  List<IHeatMeterDataGather> queryHeatMeterDataWithLimit(String  meterNo,Date startDate,Date endDate,int limit) throws Exception{
			List<IHeatMeterDataGather> result = new ArrayList<IHeatMeterDataGather>();
				if(org.apache.commons.lang3.StringUtils.isBlank(meterNo)) return result;
					String hql = 		"from IHeatMeterDataGather amd " +
							"where amd.meterNo='"+meterNo+"' " +
							"and amd.recordTime between :startTime and :endTime";
					//查询时间设置
					Date recordTimeStart = CalendarUtils.getMinCalBasedSrcCal(startDate);
					Date recordTimeEnd = CalendarUtils.getMaxCalBasedSrcCal(endDate);
					//运行时 修改为getCurrentSession
//					Query query = this.getSession().createQuery(hql)
					Query query = this.getCurrentSession().createQuery(hql)
							.setTimestamp("startTime", recordTimeStart)
							.setTimestamp("endTime", recordTimeEnd);
					if(limit!=0) {
					query.setMaxResults(limit);//限制结果集为1行
					}
					result =query.list();
				return result;
	}
	
	
	/**
	 * 查询数据库中某一热量表号 最后一次上传时间
	 * */	
	@Override
	public Date queryLastUploadDate(String  meterNo)  throws Exception {
		String sql = "SELECT t_record_time FROM p_heat_meta_data WHERE t_meter_no = ? ORDER BY t_record_time DESC LIMIT 0,1;";
		if(org.apache.commons.lang3.StringUtils.isBlank(meterNo)) return null;
		Date date = null;
		try {
			 date = jdbcTemplate.queryForObject(sql, new Object[] {meterNo}, Date.class);
		} catch (Exception e) {
			return null;
		}
		return date;
	}
	
	/**
	 * @return the iResourceAccessControlDao
	 */
	public IResourceAccessControlDao getiResourceAccessControlDao() {
		return iResourceAccessControlDao;
	}

	/**
	 * @param iResourceAccessControlDao the iResourceAccessControlDao to set
	 */
	public void setiResourceAccessControlDao(
			IResourceAccessControlDao iResourceAccessControlDao) {
		this.iResourceAccessControlDao = iResourceAccessControlDao;
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
}
